// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

//! 请求记录器实现

use std::collections::VecDeque;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use crc32fast::Hasher;

use crate::ipc::recorder::proto_types::{
    RecordFileHeader, RequestRecord, ArgumentRecord, RecordBatch,
    ArgumentType, ArgumentFlags, RecordStatistics, RecordFileFooter, RecordIndex
};
use crate::ipc::message::{Request, Argument, ArgumentFlag};

use super::{
    RecorderConfig, RecorderError, RecorderStats,
    format::{RecordWriter, create_writer, create_default_header}
};

/// 请求记录器
pub struct RequestLogger {
    config: RecorderConfig,
    file_writer: Box<dyn RecordWriter>,
    record_counter: AtomicU64,
    current_batch: RecordBatch,
    last_flush: Instant,
    stats: RecorderStats,
    file_header: RecordFileHeader,
    record_indices: Vec<RecordIndex>,
}

impl RequestLogger {
    /// 创建新的记录器
    pub fn new(config: RecorderConfig) -> Result<Self, RecorderError> {
        let mut file_writer = create_writer(&config.output_path, config.format)?;
        let file_header = create_default_header();
        
        // 写入文件头部
        file_writer.write_header(&file_header)?;
        
        Ok(Self {
            config,
            file_writer,
            record_counter: AtomicU64::new(0),
            current_batch: RecordBatch {
                records: Vec::new(),
                batch_timestamp_ns: 0,
                batch_id: 0,
            },
            last_flush: Instant::now(),
            stats: RecorderStats::default(),
            file_header,
            record_indices: Vec::new(),
        })
    }
    
    /// 记录单个请求
    pub fn log_request(&mut self, request: &Request) -> Result<(), RecorderError> {
        let record = self.request_to_record(request)?;
        self.add_record_to_batch(record)?;
        
        // 检查是否需要刷新
        if self.should_flush() {
            self.flush()?;
        }
        
        Ok(())
    }
    
    /// 批量记录请求
    pub fn log_requests(&mut self, requests: &[Request]) -> Result<(), RecorderError> {
        for request in requests {
            let record = self.request_to_record(request)?;
            self.add_record_to_batch(record)?;
        }
        
        // 批量写入后强制刷新
        self.flush()
    }
    
    /// 手动刷新缓冲区
    pub fn flush(&mut self) -> Result<(), RecorderError> {
        if self.current_batch.records.is_empty() {
            return Ok(());
        }
        
        // 更新批次时间戳
        self.current_batch.batch_timestamp_ns = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap_or_default()
            .as_nanos() as u64;
        
        // 记录当前位置用于索引
        let file_position = self.file_writer.position()?;
        
        // 写入批次
        self.file_writer.write_batch(&self.current_batch)?;
        self.file_writer.flush()?;
        
        // 更新索引
        for record in &self.current_batch.records {
            self.record_indices.push(RecordIndex {
                record_id: record.record_id,
                file_offset: file_position,
                record_size: 0, // TODO: 计算实际记录大小
                timestamp_ns: record.timestamp_ns,
            });
        }
        
        // 更新统计信息
        self.stats.total_requests += self.current_batch.records.len() as u64;
        self.stats.flush_count += 1;
        self.stats.last_flush = Some(Instant::now());
        self.last_flush = Instant::now();
        
        // 清空当前批次
        self.current_batch.records.clear();
        self.current_batch.batch_id += 1;
        
        Ok(())
    }
    
    /// 关闭记录器并写入文件尾部
    pub fn close(mut self) -> Result<(), RecorderError> {
        // 刷新剩余数据
        self.flush()?;
        
        // 更新文件头部统计信息
        let mut updated_header = self.file_header.clone();
        if let Some(stats) = &mut updated_header.statistics {
            stats.total_records = self.stats.total_requests;
            stats.total_size_bytes = self.stats.total_bytes;
            if let Some(first_index) = self.record_indices.first() {
                stats.first_timestamp_ns = first_index.timestamp_ns;
            }
            if let Some(last_index) = self.record_indices.last() {
                stats.last_timestamp_ns = last_index.timestamp_ns;
            }
        }
        
        // 写入文件尾部
        let footer = RecordFileFooter {
            indices: self.record_indices,
            header_checksum: 0, // TODO: 计算头部校验和
            data_checksum: 0,   // TODO: 计算数据校验和
        };
        
        self.file_writer.write_footer(&footer)?;
        self.file_writer.sync()?;
        
        Ok(())
    }
    
    /// 获取记录统计信息
    pub fn stats(&self) -> &RecorderStats {
        &self.stats
    }
    
    /// 将Request转换为RequestRecord
    fn request_to_record(&self, request: &Request) -> Result<RequestRecord, RecorderError> {
        let record_id = self.record_counter.fetch_add(1, Ordering::SeqCst);
        let timestamp_ns = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap_or_default()
            .as_nanos() as u64;
        
        // 序列化参数数据
        let (raw_data, arguments) = self.serialize_arguments(request.arguments())?;
        
        // 计算数据校验和
        let mut hasher = Hasher::new();
        hasher.update(&raw_data);
        let data_checksum = hasher.finalize();
        
        // 获取线程ID
        let thread_id = get_current_thread_id();
        
        Ok(RequestRecord {
            record_id,
            timestamp_ns,
            thread_id,
            method_id: request.method_id(),
            arguments,
            raw_data,
            data_checksum,
        })
    }
    
    /// 序列化参数列表
    fn serialize_arguments(&self, arguments: &[Argument]) -> Result<(Vec<u8>, Vec<ArgumentRecord>), RecorderError> {
        let mut raw_data = Vec::new();
        let mut arg_records = Vec::new();
        
        for (index, arg) in arguments.iter().enumerate() {
            let data_offset = raw_data.len() as u64;
            
            // 获取参数数据
            let arg_data = unsafe {
                std::slice::from_raw_parts(arg.ptr() as *const u8, arg.size())
            };
            
            // 添加对齐填充
            let alignment = arg.align();
            let padding = (alignment - (raw_data.len() % alignment)) % alignment;
            raw_data.extend(std::iter::repeat(0u8).take(padding));
            
            let aligned_offset = raw_data.len() as u64;
            raw_data.extend_from_slice(arg_data);
            
            // 创建参数记录
            arg_records.push(ArgumentRecord {
                arg_index: index as u32,
                arg_type: self.convert_argument_type(arg),
                size_bytes: arg.size() as u64,
                alignment: alignment as u32,
                flags: Some(self.convert_argument_flags(arg.flag())),
                data_offset: aligned_offset,
            });
        }
        
        Ok((raw_data, arg_records))
    }
    
    /// 转换参数类型
    fn convert_argument_type(&self, arg: &Argument) -> i32 {
        // 根据参数特征判断类型
        if arg.size() <= 8 {
            ArgumentType::ArgTypeValue as i32
        } else if arg.flag().contains(ArgumentFlag::ARG_VIRT) {
            ArgumentType::ArgTypeHandle as i32
        } else {
            ArgumentType::ArgTypeBuffer as i32
        }
    }
    
    /// 转换参数标志
    fn convert_argument_flags(&self, flag: ArgumentFlag) -> ArgumentFlags {
        ArgumentFlags {
            is_input: flag.contains(ArgumentFlag::ARG_IN),
            is_output: flag.contains(ArgumentFlag::ARG_OUT),
            is_const: false, // TODO: 从flag中推断
            is_optional: false, // TODO: 从flag中推断
        }
    }
    
    /// 将记录添加到当前批次
    fn add_record_to_batch(&mut self, record: RequestRecord) -> Result<(), RecorderError> {
        self.current_batch.records.push(record);
        Ok(())
    }
    
    /// 检查是否应该刷新
    fn should_flush(&self) -> bool {
        // 检查缓冲区大小
        if self.current_batch.records.len() >= self.config.buffer_size / 100 {
            return true;
        }
        
        // 检查时间间隔（1秒）
        if self.last_flush.elapsed().as_secs() >= 1 {
            return true;
        }
        
        false
    }
}

impl Drop for RequestLogger {
    fn drop(&mut self) {
        // 尝试刷新剩余数据，忽略错误
        let _ = self.flush();
    }
}

/// 获取当前线程ID
fn get_current_thread_id() -> u64 {
    // 使用线程本地存储或系统调用获取线程ID
    // 这里简化实现，使用线程指针作为ID
    std::thread::current().id().as_u64().get()
}

/// 扩展trait：为Request添加记录功能
pub trait RequestRecording {
    /// 记录当前请求
    fn record_to(&self, logger: &mut RequestLogger) -> Result<(), RecorderError>;
}

impl<'a> RequestRecording for Request<'a> {
    fn record_to(&self, logger: &mut RequestLogger) -> Result<(), RecorderError> {
        logger.log_request(self)
    }
}